package liquidfs.data.ops;

import java.util.*;

import utility.*;

import com.thoughtworks.xstream.annotations.*;

import liquidfs.data.*;

public abstract class AbstractOperation<T> implements Operation<T> {

   private static long nextID = 0;
   
   private PeerDevice origin;
   
   @XStreamSchemaDefault("0")
   @XStreamSchemaMinimum("0")
   private int maximumInputSize = 0;
   
   @XStreamSchemaDefault("0")
   @XStreamSchemaMinimum("0")
   private int maximumOutputSize = 0;
   private Set<PeerDevice> reached = new TreeSet<PeerDevice>();
   
   @XStreamAsAttribute()
   @XStreamSchemaMinimum("0")
   private long id = nextID++;
   
   public AbstractOperation (PeerDevice origin) {
      this.origin = origin;
   }
   
   public void addReachedDevice (PeerDevice device) {
      reached.add(device);
   }
   
   public void addReachedDevices (Collection<PeerDevice> devices) {
      reached.addAll(devices);
   }
   
   public boolean reached (PeerDevice device) {
      return reached.contains(device);
   }
   
   public Set<PeerDevice> getReachedDevices () {
      return reached;
   }
   
   protected void setMaximumIO (int maximumInput, int maximumOutput) {
      this.maximumInputSize = maximumInput;
      this.maximumOutputSize = maximumOutput;
   }
   
   protected void setMaximumInputSize (int maximumInput) {
      this.maximumInputSize = maximumInput;
   }
   
   protected void setMaximumOutputSize (int maximumOutput) {
      this.maximumOutputSize = maximumOutput;
   }
   
   @Override
   public PeerDevice getOrigin () {
      return this.origin;
   }
   
   @Override
   public boolean isModification () {
      return false;
   }
   
   @Override
   public Notification getNotification () {
      return null;
   }
   
   @Override
   public int getMaximumInputSize () {
      return maximumInputSize;
   }
   
   @Override
   public int getMaximumOutputSize () {
      return maximumOutputSize;
   }
   
   @Override
   public long getID () {
      return id;
   }
   
   @Override
   public String toString () {
      return this.getClass().getSimpleName();
   }
}
